package org.linlinjava.litemall.db.domain;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.apache.ibatis.type.IntegerTypeHandler;
import org.linlinjava.litemall.db.handler.ArrayObjectJsonTypeHandler;
import org.linlinjava.litemall.db.handler.IntegerArrayJsonTypeHandler;
import org.linlinjava.litemall.db.handler.ListIntegerTypeHandler;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * litemall秩序
 *
 * @author yliyun
 * @date 2022/09/15
 */
@Data
@TableName(value = "litemall_order",autoResultMap = true)
public class LitemallOrder implements Delayed {
    /**
     * 是 删除
     */
    public static final Boolean IS_DELETED = Deleted.IS_DELETED.value();

    /**
     * 沒有 删除
     */
    public static final Boolean NOT_DELETED = Deleted.NOT_DELETED.value();

    /**
     * id
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 订单名称
     */
    private String name;

    /**
     * 用户id
     */
    private Integer userId;

    /**
     * 商店id
     */
    private Integer shopId;

    /**
     * 订单sn
     */
    private String orderSn;

    /**
     * 商品ids
     */
    @TableField(typeHandler = ListIntegerTypeHandler.class)
    private List<Integer> goodsIds;

    /**
     * 套餐ids
     */
    @TableField(typeHandler = ListIntegerTypeHandler.class)
    private List<Integer> packageIds;

    /**
     * 序列号
     */
    private Integer serialNo;

    /**
     * 设备没有
     */
    private String deviceNo;

    /**
     * 订单状态
     */
    private Short orderStatus;

    /**
     * 退款状态
     */
    private Byte refundStatus;

    /**
     * 评估状况
     */
    private Byte evaluationStatus;

    /**
     * 了状态
     */
    private Byte madeStatus;

    /**
     * 订单类型
     */
    private Byte orderType;

    /**
     * 原始sn
     */
    private String originalSn;

    /**
     * 是重复
     */
    private Boolean isRepeat;

    /**
     * 是退款
     */
    private Boolean isRefund;

    /**
     * 收货人
     */
    private String consignee;

    /**
     * 移动
     */
    private String mobile;

    /**
     * 地址
     */
    private String address;

    /**
     * 备注消息
     */
    private String message;

    /**
     * 商品价格
     */
    private BigDecimal goodsPrice;

    /**
     * 运费价格
     */
    private BigDecimal freightPrice;

    /**
     * 优惠价格
     */
    private BigDecimal couponPrice;

    /**
     * 整体价格
     */
    private BigDecimal integralPrice;

    /**
     * 团购价格
     */
    private BigDecimal grouponPrice;

    /**
     * 订单价格
     */
    private BigDecimal orderPrice;

    /**
     * 税价格
     */
    private BigDecimal taxPrice;

    /**
     * 实际价格
     */
    private BigDecimal actualPrice;

    /**
     * 货币
     */
    private String currency;

    /**
     * 支付类型
     */
    private Byte payType;

    /**
     * 支付id
     */
    private String payId;

    /**
     * 贸易没有
     */
    private String outTradeNo;

    /**
     * 事务处理标识
     */
    private String transationId;

    /**
     * 支付时间
     */
    //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
    private LocalDateTime payTime;

    /**
     * 订单来源
     */
    private Byte orderSource;

    /**
     * 船状态
     */
    private Byte shipStatus;

    /**
     * 船sn
     */
    private String shipSn;

    /**
     * 航道
     */
    private String shipChannel;

    /**
     * 船时间
     */
    private LocalDateTime shipTime;

    /**
     * 船话
     */
    private String shipRemark;

    /**
     * 收到开始时间
     */
    private LocalDateTime receiptStartTime;

    /**
     * 收到结束时间
     */
    private LocalDateTime receiptEndTime;

    /**
     * 外部id
     */
    private Integer externalId;

    /**
     * 确认时间
     */
    private LocalDateTime confirmTime;

    /**
     * 评论
     */
    private Short comments;

    /**
     * 描述
     */
    private String description;

    /**
     * 工作单
     */
    private Boolean shopOrder;

    /**
     * 结束时间
     */
    private LocalDateTime endTime;

    /**
     * 结束一年
     */
    private Integer endYear;

    /**
     * 月结束
     */
    private Integer endMonth;

    /**
     * 添加时间
     */
    @TableField(fill = FieldFill.INSERT) // 插入 和 更新时 自动填充
    private LocalDateTime addTime;

    @TableField(fill = FieldFill.UPDATE) // 插入 和 更新时 自动填充
    private LocalDateTime updateTime;

    /**
     * 删除
     */
    @TableLogic
    private Boolean deleted;

    /**
     * 售后地位
     */
    private Boolean aftersaleStatus;

    /**
     * 点
     */
    private BigDecimal points;

    /**
     * 例id
     */
    private Integer exId;

    /**
     * 付费会员id
     */
    private Integer payMemberId;

    /**
     * 结合优惠券id
     */
    private Integer bindCouponId;

    /**
     * serinal数量
     */
    private Integer serinalNumber;

    /**
     * 成员身份
     */
    private Integer memberId;

    /**
     * 会员价格
     */
    private BigDecimal memberPrice;

    private BigDecimal gstPrice;
    private BigDecimal pstPrice;
    private BigDecimal hstPrice;

    private BigDecimal memberPer;

    private String wxMemberSource;

    private String employeeId;

    private LocalDateTime completeTime;

    /**
     * 时间
     */
    @TableField(exist = false)
    private long time;
    @TableField(exist = false)
    private String username;
    @TableField(exist = false)
    private String shopName;

    @TableField(exist = false)
    private List<LitemallOrderGoods> orderGoods;



    /**
     * 会延迟
     *
     * @param unit 单位
     * @return long
     */
    @Override
    public long getDelay(TimeUnit unit) {

        return time - System.currentTimeMillis();
    }

    /**
     * 比较
     *
     * @param o o
     * @return int
     */
    @Override
    public int compareTo(Delayed o) {
        LitemallOrder order = (LitemallOrder) o;
        long diff = time - order.time;
        if (diff <= 0) {
            return -1;
        } else {
            return 1;
        }
    }

    public enum Deleted {
        NOT_DELETED(new Boolean("0"), "未删除"),
        IS_DELETED(new Boolean("1"), "已删除");

        private final Boolean value;

        private final String name;

        Deleted(Boolean value, String name) {
            this.value = value;
            this.name = name;
        }

        public Boolean getValue() {
            return this.value;
        }

        public Boolean value() {
            return this.value;
        }

        public String getName() {
            return this.name;
        }
    }

    public enum Column {
        id("id", "id", "INTEGER", false),
        userId("user_id", "userId", "INTEGER", false),
        shopId("shop_id", "shopId", "INTEGER", false),
        orderSn("order_sn", "orderSn", "VARCHAR", false),
        serialNo("serial_no", "serialNo", "INTEGER", false),
        deviceNo("device_no", "deviceNo", "VARCHAR", false),
        orderStatus("order_status", "orderStatus", "SMALLINT", false),
        refundStatus("refund_status", "refundStatus", "TINYINT", false),
        evaluationStatus("evaluation_status", "evaluationStatus", "TINYINT", false),
        madeStatus("made_status", "madeStatus", "TINYINT", false),
        orderType("order_type", "orderType", "TINYINT", false),
        originalSn("original_sn", "originalSn", "VARCHAR", false),
        isRepeat("is_repeat", "isRepeat", "BIT", false),
        isRefund("is_refund", "isRefund", "BIT", false),
        consignee("consignee", "consignee", "VARCHAR", false),
        mobile("mobile", "mobile", "VARCHAR", false),
        address("address", "address", "VARCHAR", false),
        message("message", "message", "VARCHAR", false),
        goodsPrice("goods_price", "goodsPrice", "DECIMAL", false),
        freightPrice("freight_price", "freightPrice", "DECIMAL", false),
        couponPrice("coupon_price", "couponPrice", "DECIMAL", false),
        integralPrice("integral_price", "integralPrice", "DECIMAL", false),
        grouponPrice("groupon_price", "grouponPrice", "DECIMAL", false),
        orderPrice("order_price", "orderPrice", "DECIMAL", false),
        taxPrice("tax_price", "taxPrice", "DECIMAL", false),
        actualPrice("actual_price", "actualPrice", "DECIMAL", false),
        currency("currency", "currency", "VARCHAR", false),
        payType("pay_type", "payType", "TINYINT", false),
        payId("pay_id", "payId", "VARCHAR", false),
        outTradeNo("out_trade_no", "outTradeNo", "VARCHAR", false),
        transationId("transation_id", "transationId", "VARCHAR", false),
        payTime("pay_time", "payTime", "TIMESTAMP", false),
        orderSource("order_source", "orderSource", "TINYINT", false),
        shipStatus("ship_status", "shipStatus", "TINYINT", false),
        shipSn("ship_sn", "shipSn", "VARCHAR", false),
        shipChannel("ship_channel", "shipChannel", "VARCHAR", false),
        shipTime("ship_time", "shipTime", "TIMESTAMP", false),
        shipRemark("ship_remark", "shipRemark", "VARCHAR", false),
        receiptStartTime("receipt_start_time", "receiptStartTime", "TIMESTAMP", false),
        receiptEndTime("receipt_end_time", "receiptEndTime", "TIMESTAMP", false),
        externalId("external_id", "externalId", "INTEGER", false),
        confirmTime("confirm_time", "confirmTime", "TIMESTAMP", false),
        comments("comments", "comments", "SMALLINT", false),
        description("description", "description", "VARCHAR", false),
        shopOrder("shop_order", "shopOrder", "BIT", false),
        endTime("end_time", "endTime", "TIMESTAMP", false),
        endYear("end_year", "endYear", "INTEGER", false),
        endMonth("end_month", "endMonth", "INTEGER", false),
        addTime("add_time", "addTime", "TIMESTAMP", false),
        updateTime("update_time", "updateTime", "TIMESTAMP", false),
        deleted("deleted", "deleted", "BIT", false),
        aftersaleStatus("aftersale_status", "aftersaleStatus", "BIT", false),
        points("points", "points", "DECIMAL", false),
        exId("ex_id", "exId", "INTEGER", false),
        payMemberId("pay_member_id", "payMemberId", "INTEGER", false),
        bindCouponId("bind_coupon_id", "bindCouponId", "INTEGER", false),
        serinalNumber("serinal_number", "serinalNumber", "INTEGER", false),
        memberId("member_id", "memberId", "INTEGER", false),
        memberPrice("member_price", "memberPrice", "DECIMAL", false);

        private static final String BEGINNING_DELIMITER = "`";

        private static final String ENDING_DELIMITER = "`";

        private final String column;

        private final boolean isColumnNameDelimited;

        private final String javaProperty;

        private final String jdbcType;

        public String value() {
            return this.column;
        }

        public String getValue() {
            return this.column;
        }

        public String getJavaProperty() {
            return this.javaProperty;
        }

        public String getJdbcType() {
            return this.jdbcType;
        }

        Column(String column, String javaProperty, String jdbcType, boolean isColumnNameDelimited) {
            this.column = column;
            this.javaProperty = javaProperty;
            this.jdbcType = jdbcType;
            this.isColumnNameDelimited = isColumnNameDelimited;
        }

        public String desc() {
            return this.getEscapedColumnName() + " DESC";
        }

        public String asc() {
            return this.getEscapedColumnName() + " ASC";
        }

        public static Column[] excludes(Column ... excludes) {
            ArrayList<Column> columns = new ArrayList<>(Arrays.asList(Column.values()));
            if (excludes != null && excludes.length > 0) {
                columns.removeAll(new ArrayList<>(Arrays.asList(excludes)));
            }
            return columns.toArray(new Column[]{});
        }

        public String getEscapedColumnName() {
            if (this.isColumnNameDelimited) {
                return new StringBuilder().append(BEGINNING_DELIMITER).append(this.column).append(ENDING_DELIMITER).toString();
            } else {
                return this.column;
            }
        }

        public String getAliasedEscapedColumnName() {
            return this.getEscapedColumnName();
        }
    }
}
